#include "segment_codes.h"
#include "ht1621b.h"
#include "LOG.h"
#include <string.h>

// 小时高位显示段码
HourHigh_STRUCT HourHighTable[] = {
    {2,{226, 227}, "1"}, // 1
    {2,{235, 226}, "2"},  // 2
    {2,{41, 195}, ":"}  // “:”
};

// 小时低位显示段码
LCD_Display_8_STRUCT LCD_Display_8Table[] = {
    {13, {201, 210, 209, 217, 218, 219, 203, 18, 19, 25, 26, 27, 202}, "0"}, // 0
    {6, {201, 202, 203, 27, 26,210}, "1"},                                            // 1
    {12, {217, 209, 210, 201, 202, 203, 211, 219, 19, 18, 25, 26}, "2"},          // 2
    {12, {217, 209, 210, 201, 202, 203, 211, 219, 27, 26, 25, 18}, "3"},          // 3
    {9, {217, 218, 219, 211, 203, 201, 202, 27, 26}, "4"},                        // 4
    {12, {201, 210, 209, 217, 218, 219, 211, 203, 27, 26, 25, 18}, "5"},          // 5
    {13, {201, 210, 209, 217, 218, 219, 211, 203, 18, 19, 25, 26, 27}, "6"},      // 6
    {8, {217, 209, 210, 201, 202, 203, 27, 26}, "7"},                             // 7
    {14, {201, 210, 209, 217, 218, 219, 211, 203, 18, 19, 25, 26, 27, 202}, "8"}, // 8
    {13, {201, 210, 209, 217, 218, 219, 211, 203, 18, 25, 26, 27, 202}, "9"},     // 9
};

// 分钟高位显示段码
LCD_Display_8_STRUCT MinuteHighTable[] = {
    {13, {185, 177, 178, 169, 186, 170, 187, 171, 43, 51, 42, 49, 50}, "0"},      // 0
    {6, {169, 170, 171, 178, 51, 50}, "1"},                                            // 1
    {12, {185, 177, 178, 169, 170, 187, 179, 171, 43, 42, 49, 50}, "2"},          // 2
    {12, {185, 177, 178, 169, 170, 187, 179, 171, 51, 42, 49, 50}, "3"},          // 3
    {9, {185, 169, 186, 170, 179, 187, 171, 51, 50}, "4"},                        // 4
    {12, {185, 177, 178, 169, 186, 187, 179, 171, 51, 42, 49, 50}, "5"},          // 5
    {13, {185, 177, 178, 169, 186, 187, 179, 171, 43, 51, 42, 49, 50}, "6"},      // 6
    {8, {185, 177, 178, 169, 170, 171, 51, 50}, "7"},                             // 7
    {14, {185, 177, 178, 169, 186, 170, 187, 179, 171, 43, 51, 42, 49, 50}, "8"}, // 8
    {13, {185, 177, 178, 169, 186, 170, 187, 179, 171, 51, 42, 49, 50}, "9"}, // 9
};

// 分钟低位显示段码
LCD_Display_8_STRUCT MinuteLowTable[] = {
    {13, {161, 153, 154, 145, 162, 146, 163, 147, 59, 67, 58, 65, 66}, "0"},      // 0
    {6, {145, 146, 147, 67, 66, 154}, "1"},                                       // 1
    {12, {161, 153, 154, 145, 146, 163, 155, 147, 59, 58, 65, 66}, "2"},          // 2
    {12, {161, 153, 154, 145, 146, 163, 155, 147, 67, 58, 65, 66}, "3"},          // 3
    {9, {161, 145, 162, 146, 163, 155, 147, 67, 66}, "4"},                        // 4
    {12, {161, 153, 154, 145, 162, 163, 155, 147, 67, 58, 65, 66}, "5"},          // 5
    {13, {161, 153, 154, 145, 162, 163, 155, 147, 59, 67, 58, 65, 66}, "6"},      // 6
    {8, {161, 153, 154, 145, 146, 147, 67, 66}, "7"},  // 7
    {14, {161, 153, 154, 145, 162, 146, 163, 155, 147, 59, 67, 58, 65, 66}, "8"}, // 8
    {13, {161, 153, 154, 145, 162, 146, 163, 155, 147, 67, 58, 65, 66}, "9"},     // 9
};

LCD_Display_8_STRUCT SecondHighTable[] = {
    {12, {73, 74, 81, 83, 121, 122, 123, 131, 129, 137, 138, 139}, "0"},      // 0
    {5, {81, 83, 121, 122, 123}, "1"},                                        // 1
    {11, {73, 74, 81, 121, 122, 123, 131, 129, 137, 130, 139}, "2"},          // 2
    {11, {73, 74, 81, 83, 121, 122, 123, 129, 137, 130, 139}, "3"},           // 3
    {9, {81, 83, 121, 122, 123, 137, 130, 138, 139}, "4"},                    // 4
    {11, {73, 74, 81, 83, 121, 123, 129, 137, 130, 138, 139}, "5"},           // 5
    {12, {73, 74, 81, 83, 121, 123, 131, 129, 137, 130, 138, 139}, "6"},      // 6
    {7, {81, 83, 121, 122, 123, 129, 137}, "7"},                              // 7
    {13, {73, 74, 81, 83, 121, 122, 123, 131, 129, 137, 130, 138, 139}, "8"}, // 8
    {12, {73, 74, 81, 83, 121, 122, 123, 129, 137, 130, 138, 139}, "9"}, // 9
};

LCD_Display_8_STRUCT SecondLowTable[] = {
    {12, {113, 114, 115, 107, 82, 89, 90, 91, 97, 98, 99, 105}, "0"},      // 0
    {5, {90, 91, 97, 98, 99}, "1"},                                        // 1
    {11, {113, 115, 107, 82, 89, 90, 97, 98, 99, 105, 106}, "2"},          // 2
    {11, {113, 115, 82, 89, 90, 91, 97, 98, 99, 105, 106}, "3"},           // 3
    {9, {113, 114, 115, 90, 91, 97, 98, 99, 106}, "4"},                    // 4
    {11, {113, 114, 115, 82, 89, 90, 91, 97, 99, 105, 106}, "5"},          // 5
    {12, {113, 114, 115, 107, 82, 89, 90, 91, 97, 99, 105, 106}, "6"},     // 6
    {7, {113, 90, 91, 97, 98, 99, 105}, "7"},  // 7
    {13, {113, 114, 115, 107, 82, 89, 90, 91, 97, 98, 99, 105, 106}, "8"}, // 8
    {12, {113, 114, 115, 82, 89, 90, 91, 97, 98, 99, 105, 106}, "9"},      // 9
};
// 设置指定段码的状态
/**
 * @brief 设置指定段码的状态
 *
 * @param segment 段码编号 (0-127)
 * @param state 状态 (0=关闭, 1=打开)
 */
void segment_set(uint8_t segment, uint8_t state)
{
    if (segment >= HT1621B_BUFFER_SIZE * 8)
    {
        LOG_WARN("Segment %d out of range (max %d)", segment, HT1621B_BUFFER_SIZE * 8 - 1);
        return; // 超出范围
    }
    
    uint8_t buffer_index = segment / 8;
    uint8_t bit_position = segment % 8;
    
    LOG_VERBOSE("Setting segment %d (buffer[%d] bit %d) to %s", 
                segment, buffer_index, bit_position, state ? "ON" : "OFF");
    
    // 获取lcd_buffer的指针
    uint8_t* lcd_buffer = ht1621b_get_lcd_buffer();
    
    if (state) {
        lcd_buffer[buffer_index] |= (1 << bit_position);
    } else {
        lcd_buffer[buffer_index] &= ~(1 << bit_position);
    }

    // 直接更新整个显示缓冲区
    // ht1621b_write_buffer(lcd_buffer, HT1621B_BUFFER_SIZE);
}



// 获取指定段码的状态
/**
 * @brief 获取指定段码的状态
 * 
 * @param seg_number 段码编号 (0-127)
 * @return 段码状态 (false=关闭, true=打开)
 */
bool segment_get(uint8_t seg_number) {
    // 检查段码编号是否有效
    if (seg_number >= 128) {
        return false;
    }
    
    // 在当前实现中，我们无法直接读取段码状态
    // 这需要HT1621B驱动支持读取功能
    return false;
}

// 清除所有段码
/**
 * @brief 清除所有段码
 */
void segment_clear_all(void) {
    LOG_VERBOSE("Clearing all segments");
    
    // 调用HT1621B的清屏函数
    uint8_t clear_buffer[32] = {0};
    ht1621b_write_buffer(clear_buffer, 32);
    
    LOG_VERBOSE("All segments cleared");
}

// 显示星期
/**
 * @brief 显示星期
 * 
 * @param weekday 星期 (1-7, 1=星期日)
 */
void segment_display_weekday(uint8_t weekday) {
    LOG_VERBOSE("Displaying weekday %d", weekday);
    
    // 清除所有星期段码
    segment_set(SEG_SUN, false);
    segment_set(SEG_SAT, false);
    segment_set(SEG_FRI, false);
    segment_set(SEG_THU, false);
    segment_set(SEG_TUE, false);
    segment_set(SEG_MON, false);
    segment_set(SEG_WED, false);
    
    // 根据输入点亮对应的星期段码
    switch (weekday) {
        case 1: // 星期日
            segment_set(SEG_SUN, true);
            break;
        case 2: // 星期一
            segment_set(SEG_MON, true);
            break;
        case 3: // 星期二
            segment_set(SEG_TUE, true);
            break;
        case 4: // 星期三
            segment_set(SEG_WED, true);
            break;
        case 5: // 星期四
            segment_set(SEG_THU, true);
            break;
        case 6: // 星期五
            segment_set(SEG_FRI, true);
            break;
        case 7: // 星期六
            segment_set(SEG_SAT, true);
            break;
        default:
            LOG_WARN("Invalid weekday %d", weekday);
            break;
    }
}

// 显示功能指示
/**
 * @brief 显示功能指示
 * 
 * @param indicator 功能指示 (0-7)
 */
void segment_display_function_indicator(uint8_t indicator,bool enable) {
    LOG_VERBOSE("Displaying function indicator %d", indicator);
        
    switch (indicator) {
        case 0: // USB连接
            segment_set(SEG_USB, enable);
            break;
        case 1: // DATE字符
            segment_set(SEG_DATE, enable);
            break;
        case 2: // 闹钟1
            segment_set(SEG_ALARM1, enable);
            break;
        case 3: // 闹钟2
            segment_set(SEG_ALARM2, enable);
            break;
        case 4: // 倒计时
            segment_set(SEG_COUNT_DOWN, enable);
            break;
        case 5: // 定时器
            segment_set(SEG_TIMER, enable);
            break;
        case 6: // 睡眠
            segment_set(SEG_SLEEP, enable);
            break;
        case 7: // 电池
            segment_set(SEG_BATTERY, enable);
            break;
        default:
            LOG_WARN("Invalid function indicator %d", indicator);
            break;
    }
}
// 显示时间（格式 HH:MM:SS），支持各部分的闪烁显示
void segment_display_RTC_time_blink(uint8_t hours, uint8_t minutes, uint8_t seconds, bool h_blink, bool m_blink, bool s_blink)
{
    // 清除所有段码
    // segment_clear_all();
    
    static uint32_t blink_counter = 0;
    blink_counter++;
    bool show_digits = (blink_counter % 20) < 10; // 50%占空比闪烁
    
    // 显示小时
    if (hours >= 10)
    {
        // 显示小时高位数字
        uint8_t hour_tens = hours / 10;
        if (hour_tens >= 1 && hour_tens <= 2) {
            // 如果启用了小时高位闪烁且当前应该隐藏，则跳过显示
            if (!(h_blink && !show_digits)) {
                for (int i = 0; i < HourHighTable[hour_tens-1].data_len && i < 2; i++) {
                    segment_set(HourHighTable[hour_tens-1].seg_data[i], true);
                }
            }
        }
    }
    
    uint8_t hour_ones = hours % 10;
    // 如果启用了小时低位闪烁且当前应该隐藏，则跳过显示
    if (!(h_blink && !show_digits)) {
        for (int i = 0; i < LCD_Display_8Table[hour_ones].data_len && i < 14; i++) {
            segment_set(LCD_Display_8Table[hour_ones].seg_data[i], true);
        }
    }

    // 显示分钟
    uint8_t minute_tens = minutes / 10;
    // 如果启用了分钟高位闪烁且当前应该隐藏，则跳过显示
    if (!(m_blink && !show_digits)) {
        for (int i = 0; i < MinuteHighTable[minute_tens].data_len && i < 14; i++) {
            segment_set(MinuteHighTable[minute_tens].seg_data[i], true);
        }
    }
    
    uint8_t minute_ones = minutes % 10;
    // 如果启用了分钟低位闪烁且当前应该隐藏，则跳过显示
    if (!(m_blink && !show_digits)) {
        for (int i = 0; i < MinuteLowTable[minute_ones].data_len && i < 14; i++) {
            segment_set(MinuteLowTable[minute_ones].seg_data[i], true);
        }
    }

    // 显示秒钟
    uint8_t second_tens = seconds / 10;
    if(second_tens > 0)
    {
        // 如果启用了秒钟高位闪烁且当前应该隐藏，则跳过显示
        if (!(s_blink && !show_digits)) {
            for (int i = 0; i < SecondHighTable[second_tens].data_len && i < 13; i++)
            {
                segment_set(SecondHighTable[second_tens].seg_data[i], true);
            }
        }
    }
    
    uint8_t second_ones = seconds % 10;
    // 如果启用了秒钟低位闪烁且当前应该隐藏，则跳过显示
    if (!(s_blink && !show_digits)) {
        for (int i = 0; i < SecondLowTable[second_ones].data_len && i < 13; i++) {
            segment_set(SecondLowTable[second_ones].seg_data[i], true);
        }
    }

    // 显示分隔符（冒号）
    // 在闪烁模式下，冒号通常保持常亮
    for (int i = 0; i < HourHighTable[2].data_len && i < 2; i++) {
        segment_set(HourHighTable[2].seg_data[i], true);
    }
}


// 显示时间（格式 HH:MM 或 HH:MM:SS）
void segment_display_RTC_time(uint8_t hours, uint8_t minutes, uint8_t seconds, bool colon_visible)
{
    // // 清除所有段码
    // segment_clear_all();

    // 显示小时
    if (hours >= 10)
    {
        // 显示小时高位数字
        uint8_t hour_tens = hours / 10;
        if (hour_tens >= 1 && hour_tens <= 2)
        {
            for (int i = 0; i < HourHighTable[hour_tens - 1].data_len && i < 2; i++)
            {
                segment_set(HourHighTable[hour_tens - 1].seg_data[i], true);
            }
        }
    }

    uint8_t hour_ones = hours % 10;
    for (int i = 0; i < LCD_Display_8Table[hour_ones].data_len && i < 14; i++)
    {
        segment_set(LCD_Display_8Table[hour_ones].seg_data[i], true);
    }

    // 显示分钟
    uint8_t minute_tens = minutes / 10;
    for (int i = 0; i < MinuteHighTable[minute_tens].data_len && i < 14; i++)
    {
        segment_set(MinuteHighTable[minute_tens].seg_data[i], true);
    }

    uint8_t minute_ones = minutes % 10;
    for (int i = 0; i < MinuteLowTable[minute_ones].data_len && i < 14; i++)
    {
        segment_set(MinuteLowTable[minute_ones].seg_data[i], true);
    }

    // 显示秒钟
    uint8_t second_tens = seconds / 10;
    if (second_tens > 0)
    {
        for (int i = 0; i < SecondHighTable[second_tens].data_len && i < 13; i++)
        {
            segment_set(SecondHighTable[second_tens].seg_data[i], true);
        }
    }

    uint8_t second_ones = seconds % 10;
    for (int i = 0; i < SecondLowTable[second_ones].data_len && i < 13; i++)
    {
        segment_set(SecondLowTable[second_ones].seg_data[i], true);
    }

    // 显示分隔符（冒号）
    if (colon_visible)
    {
        // 使用HourHighTable中定义的冒号段码
        for (int i = 0; i < HourHighTable[2].data_len && i < 2; i++)
        {
            segment_set(HourHighTable[2].seg_data[i], true);
        }
    }
}

void segment_display_date(uint8_t month, uint8_t day, uint8_t weekday)
{
    // 清除所有段码
    segment_clear_all();

    // 显示月份（2位数字）- 前2位用小时位显示
    uint8_t month_tens = month / 10;
    uint8_t month_ones = month % 10;

    // 显示月份十位 - 使用小时高位显示
    if (month_tens > 0)
    {
        for (int i = 0; i < HourHighTable[month_tens].data_len && i < 2; i++)
        {
            segment_set(HourHighTable[month_tens].seg_data[i], true);
        }
    }

    // 显示月份个位 - 使用小时个位显示
    for (int i = 0; i < LCD_Display_8Table[month_ones].data_len && i < 14; i++)
    {
        segment_set(LCD_Display_8Table[month_ones].seg_data[i], true);
    }

    // 显示日期（2位数字）- 后2位用分钟位显示
    uint8_t day_tens = day / 10;
    uint8_t day_ones = day % 10;

    // 显示日期十位 - 使用分钟高位显示
    if (day_tens > 0)
    {
        for (int i = 0; i < MinuteHighTable[day_tens].data_len && i < 14; i++)
        {
            segment_set(MinuteHighTable[day_tens].seg_data[i], true);
        }
    }

    // 显示日期个位 - 使用分钟低位显示
    for (int i = 0; i < MinuteLowTable[day_ones].data_len && i < 14; i++)
    {
        segment_set(MinuteLowTable[day_ones].seg_data[i], true);
    }

    // 显示星期
    segment_display_weekday(weekday);

    // 显示DATE指示符
    segment_set(SEG_DATE, true);
}

void segment_display_year(uint8_t year)
{
    // 清除所有段码
    segment_clear_all();

    // 显示完整的4位年份 - 前2位用小时位显示，后2位用分钟位显示
    // 年份前两位（世纪部分）- 使用小时位显示
    // 由于year参数只包含后两位，我们需要确定前两位
    // 假设当前是21世纪（2000-2099年）

    // 显示世纪十位（数字2）- 使用小时高位显示
    for (int i = 0; i < HourHighTable[1].data_len; i++)
    {
        segment_set(HourHighTable[1].seg_data[i], true);
    }

    // 显示世纪个位（数字0）- 使用小时个位显示
    for (int i = 0; i < LCD_Display_8Table[0].data_len && i < 14; i++)
    {
        segment_set(LCD_Display_8Table[0].seg_data[i], true);
    }

    // 显示年份后两位（XX）- 用分钟位显示
    uint8_t year_tens = year / 10;  // 年份十位
    uint8_t year_ones = year % 10;   // 年份个位

    // 显示年份十位 - 使用分钟高位显示
    if (year_tens > 0)
    {
        for (int i = 0; i < MinuteHighTable[year_tens].data_len && i < 14; i++)
        {
            segment_set(MinuteHighTable[year_tens].seg_data[i], true);
        }
    }

    // 显示年份个位 - 使用分钟低位显示
    for (int i = 0; i < MinuteLowTable[year_ones].data_len && i < 14; i++)
    {
        segment_set(MinuteLowTable[year_ones].seg_data[i], true);
    }

    // 显示DATE指示符
    segment_set(SEG_DATE, true);
}

void segment_display_charge_status(void)
{
    // 清除所有段码
    segment_clear_all();
    
    // 显示充电状态
    segment_set(SEG_BATTERY, true);
}

